package com.canaan.business.service.inOutStock.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.hutool.core.util.StrUtil;
import com.canaan.business.common.enums.agv.AgvEnum;
import com.canaan.business.common.enums.inOutStock.InOrderStatusEnum;
import com.canaan.business.common.enums.storehouse.StorehouseStockStatusEnum;
import com.canaan.business.common.helper.EmptyStockHelper;
import com.canaan.business.domain.basic.WmsStorehouseLocation;
import com.canaan.business.domain.bill.TrayDetail;
import com.canaan.business.domain.inOutStock.AdjustLocationBillDetail;
import com.canaan.business.domain.storehouse.WmsStorehouseStock;
import com.canaan.business.domain.vo.WmsStorehouseStockVo;
import com.canaan.business.service.agv.IAgvTaskDispatchService;
import com.canaan.business.service.basic.IWmsStorehouseLocationService;
import com.canaan.business.service.bill.ITrayDetailService;
import com.canaan.business.service.inOutStock.IAdjustLocationBillDetailService;
import com.canaan.business.service.storehouse.IStorehouseStockStrategyService;
import com.canaan.business.service.storehouse.IWmsStorehouseStockService;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.TableNoUtil;
import com.canaan.common.utils.uuid.UUID;
import com.canaan.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.canaan.business.mapper.inOutStock.AdjustLocationBillMapper;
import com.canaan.business.domain.inOutStock.AdjustLocationBill;
import com.canaan.business.service.inOutStock.IAdjustLocationBillService;
import com.canaan.common.annotation.TableName;
/**
 * 调库单Service业务层处理
 *
 * @author canaan
 * @date 2025-03-29
 */
@Service
@Slf4j
public class AdjustLocationBillServiceImpl implements IAdjustLocationBillService {
    @Resource
    private AdjustLocationBillMapper adjustLocationBillMapper;
    @Resource
    private IAdjustLocationBillDetailService adjustLocationBillDetailService;
    @Resource
    private IWmsStorehouseStockService storehouseStockService;
    @Resource
    private IWmsStorehouseLocationService locationService;
    @Resource
    private IStorehouseStockStrategyService storehouseStockStrategyService;
    @Resource
    private ITrayDetailService trayDetailService;
    @Resource
    private IAgvTaskDispatchService agvTaskDispatchService;
    @Resource
    private EmptyStockHelper emptyStockHelper;
    /**
     * 查询调库单
     *
     * @param id 调库单主键
     * @return 调库单
     */
    @Override
    public AdjustLocationBill selectAdjustLocationBillById(Long id) {
        return adjustLocationBillMapper.selectAdjustLocationBillById(id);
    }

    /**
     * 查询调库单列表
     *
     * @param adjustLocationBill 调库单
     * @return 调库单
     */
    @Override
    public List<AdjustLocationBill> selectAdjustLocationBillList(AdjustLocationBill adjustLocationBill) {
        return adjustLocationBillMapper.selectAdjustLocationBillList(adjustLocationBill);
    }

    /**
     * 新增调库单
     *
     * @param adjustLocationBill 调库单
     * @return 结果
     */
    @Override
    public int insertAdjustLocationBill(AdjustLocationBill adjustLocationBill) {
        if(StringUtils.isBlank(adjustLocationBill.getNo())){
            adjustLocationBill.setNo("A"+TableNoUtil.getNo(AdjustLocationBill.class));
        }
        adjustLocationBill.setCreateBy(SecurityUtils.getUsername());
        adjustLocationBill.setCreateTime(DateUtils.getNowDate());
        return adjustLocationBillMapper.insertAdjustLocationBill(adjustLocationBill);
    }

    /**
     * 批量新增调库单
     *
     * @param adjustLocationBillList 调库单列表
     * @return 结果
     */
    @Override
    public int batchInsertAdjustLocationBill(List<AdjustLocationBill> adjustLocationBillList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (AdjustLocationBill adjustLocationBill : adjustLocationBillList){
            if(StringUtils.isBlank(adjustLocationBill.getNo())){
                adjustLocationBill.setNo("A"+TableNoUtil.getNo(AdjustLocationBill.class));
            }
            adjustLocationBill.setCreateBy(username);
            adjustLocationBill.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<adjustLocationBillList.size();) {
            int endIndex = i+500;
            if (endIndex > adjustLocationBillList.size()) {
                endIndex = adjustLocationBillList.size();
            }
            insertNum = insertNum + adjustLocationBillMapper.batchInsertAdjustLocationBill(adjustLocationBillList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改调库单
     *
     * @param adjustLocationBill 调库单
     * @return 结果
     */
    @Override
    public int updateAdjustLocationBill(AdjustLocationBill adjustLocationBill) {
        if(StringUtils.isEmpty(adjustLocationBill.getUpdateBy())) {
            adjustLocationBill.setUpdateBy(SecurityUtils.getUsername());
        }
        adjustLocationBill.setUpdateTime(DateUtils.getNowDate());
        return adjustLocationBillMapper.updateAdjustLocationBill(adjustLocationBill);
    }

    /**
     * 批量修改调库单
     *
     * @param adjustLocationBillList 调库单列表
     * @return 结果
     */
    @Override
    public int batchUpdateAdjustLocationBill(List<AdjustLocationBill> adjustLocationBillList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (AdjustLocationBill adjustLocationBill : adjustLocationBillList){
            adjustLocationBill.setUpdateBy(username);
            adjustLocationBill.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<adjustLocationBillList.size();) {
            int endIndex = i+500;
            if (endIndex > adjustLocationBillList.size()) {
                endIndex = adjustLocationBillList.size();
            }
            updateNum = updateNum + adjustLocationBillMapper.batchUpdateAdjustLocationBill(adjustLocationBillList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除调库单
     *
     * @param ids 需要删除的调库单主键集合
     * @return 结果
     */
    @Override
    public int deleteAdjustLocationBillByIds(Long[] ids) {
        return adjustLocationBillMapper.deleteAdjustLocationBillByIds(ids);
    }

    /**
     * 删除调库单信息
     *
     * @param id 调库单主键
     * @return 结果
     */
    @Override
    public int deleteAdjustLocationBillById(Long id) {
        return adjustLocationBillMapper.deleteAdjustLocationBillById(id);
    }

    /**
     * 查询调库单
     *
     * @param no 编号
     * @return 调库单
     */
    @Override
    public AdjustLocationBill selectAdjustLocationBillByNo(String no) {
        return adjustLocationBillMapper.selectAdjustLocationBillByNo(no);
    }

    /**
     * 批量删除调库单
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteAdjustLocationBillByNos(String[] nos) {
        return adjustLocationBillMapper.deleteAdjustLocationBillByNos(nos);
    }

    /**
     * 删除调库单信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteAdjustLocationBillByNo(String no) {
        return adjustLocationBillMapper.deleteAdjustLocationBillByNo(no);
    }

    /**
     * 分析调库单
     */
    public WmsStorehouseLocation generateAdjustDestLocation(String locationNo,String isInner,String innerLocation){
        if(StrUtil.equalsAnyIgnoreCase(isInner,"1")){
            WmsStorehouseStock refStock=storehouseStockService.selectWmsStorehouseStockByLocationNo(innerLocation);
            if(refStock!=null){
                if(StorehouseStockStatusEnum.LOCK.getCode().equals(refStock.getStatus())){
                    return null;
                }
                WmsStorehouseLocation adjustLocation=locationService.selectWmsStorehouseLocationByNo(innerLocation);
                if(adjustLocation==null){
                    throw new RuntimeException("里库"+locationNo+"关联库位"+innerLocation+"不存在");
                }
                if(StringUtils.isNotEmpty(refStock.getContainerNo())){
                    boolean isEmptyTray=false;
                    String productNo="";
                    boolean checkProduct=false;
                    if(StringUtils.isEmpty(refStock.getTrayNo())){
                        isEmptyTray=true;
                    }
                    else{
                        TrayDetail query=new TrayDetail();
                        query.setTrayNo(refStock.getTrayNo());
                        query.setDelFlag("0");
                        List<TrayDetail> trayDetails=trayDetailService.selectTrayDetailList(query);
                        if(trayDetails!=null&&trayDetails.size()!=0){
                            productNo=trayDetails.get(0).getProductNo();
                            checkProduct=true;
                        }
                    }
                    WmsStorehouseLocation destLocation= emptyStockHelper.analyseInStock("",productNo,checkProduct,isEmptyTray);
                    /*WmsStorehouseStockVo adjustDestLocationStock=storehouseStockStrategyService.selectNearByEmptyLocation(adjustLocation);
                    if(adjustDestLocationStock==null){
                        throw new RuntimeException("成品仓不存在空库位调库");
                    }
                    WmsStorehouseLocation destLocation=locationService.selectWmsStorehouseLocationByNo(adjustDestLocationStock.getStorehouseLocationNo());
                     */
                    if(destLocation==null){
                        throw new RuntimeException("目标库位不存在");
                    }
                    return destLocation;
                }
            }
        }
        return null;
    }

    /**
     * 生成调库单
     */
    public void generateAdjustLocationBill(WmsStorehouseStock sourceStock,WmsStorehouseLocation sourceLocation, WmsStorehouseStock destStock,WmsStorehouseLocation destLocation,String billNo){
        //创建调库单
        AdjustLocationBill adjustLocationBill=new AdjustLocationBill();
        adjustLocationBill.setNo("A"+TableNoUtil.getNo(AdjustLocationBill.class));
        adjustLocationBill.setSourceLocation(sourceStock.getStorehouseLocationNo());
        adjustLocationBill.setDestLocation(destStock.getStorehouseLocationNo());
        adjustLocationBill.setOrderStatus(InOrderStatusEnum.NEW.getCode());
        adjustLocationBill.setShelfNo(sourceStock.getContainerNo());
        adjustLocationBill.setTrayNo(sourceStock.getTrayNo());
        adjustLocationBill.setRelOrderNo(billNo);
        adjustLocationBillMapper.insertAdjustLocationBill(adjustLocationBill);
        //创建AGV任务
        agvTaskDispatchService.createTaskDispatch(adjustLocationBill.getNo(),sourceLocation,destLocation, AgvEnum.TASK_TYPE.ADJUST,
                sourceStock.getContainerNo(),sourceStock.getTrayNo());
        //获取托盘明细
        TrayDetail adjustTrayDetailQuery=new TrayDetail();
        adjustTrayDetailQuery.setTrayNo(sourceStock.getTrayNo());
        adjustTrayDetailQuery.setDelFlag("0");
        List<TrayDetail> adjustTrayDetails=trayDetailService.selectTrayDetailList(adjustTrayDetailQuery);
        if(adjustTrayDetails==null||adjustTrayDetails.size()==0){
            log.error("托盘"+destStock.getTrayNo()+"不存在明细数据");
        }
        //创建调库单明细
        List<AdjustLocationBillDetail> adjustLocationDetailBills=new ArrayList<>();
        for(TrayDetail item:adjustTrayDetails) {
            AdjustLocationBillDetail adjustLocationBillDetail = new AdjustLocationBillDetail();
            adjustLocationBillDetail.setNo(TableNoUtil.getNo(AdjustLocationBillDetail.class));
            adjustLocationBillDetail.setOrderNo(adjustLocationBill.getNo());
            adjustLocationBillDetail.setProductNo(item.getProductNo());
            adjustLocationBillDetail.setProductName(item.getProductName());
            adjustLocationBillDetail.setProductUnit(item.getProductUnit());
            adjustLocationBillDetail.setQty(item.getQty());
            adjustLocationBillDetail.setStatus(InOrderStatusEnum.NEW.getCode());
            adjustLocationBillDetail.setBatchNo(item.getBatchNo());
            adjustLocationDetailBills.add(adjustLocationBillDetail);
        }
        adjustLocationBillDetailService.batchInsertAdjustLocationBillDetail(adjustLocationDetailBills);
    }
}
